﻿using System;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Controls;
using Atha.Clients.Silverlight.Services;
using Atha.Clients.ViewModels;

namespace Atha.Clients.Silverlight
{
	public partial class MainPage : UserControl
	{
		private readonly MainViewModel _viewModel;

		public MainPage()
		{
			InitializeComponent();

			this.Loaded += new RoutedEventHandler(MainPage_Loaded);

			this._viewModel = new MainViewModel(() => new TestScriptsReader(), readPath => new TestScriptReader(readPath), () => new TestScriptWriter(), new ClientTestRunner(), notify => MessageBox.Show(notify.Message), () => "test.py", () => "");

			this.DataContext = this._viewModel;
		}

		private void MainPage_Loaded(object sender, RoutedEventArgs e)
		{
			this._viewModel.OpenTests.ClickCommand.Execute(null);
		}
	}

	public class TestScriptsReader : ITestScriptsReader
	{
		public void GetScripts(Action<ITestScript[]> callback)
		{
			var testClient = new AthaTestServiceClient();

			Observable.FromEventPattern<OpenTestsCompletedEventArgs>(testClient, "OpenTestsCompleted").Subscribe(e =>
			{
				if (e.EventArgs.Cancelled) return;

				var testScripts = new List<ITestScript>();

				if (e.EventArgs.Error == null)
				{
					testScripts = new List<ITestScript>(e.EventArgs.Result.Count);

					foreach (var script in e.EventArgs.Result)
					{
						ITestScript testScript = new BasicTestScript(script.Language, script.Name, script.Content);

						testScripts.Add(testScript);
					}
				}
				else
				{
					// TODO: remove mbox dependency
					MessageBox.Show("Error: " + e.EventArgs.Error.Message, "Error", MessageBoxButton.OK);
				}

				testClient.CloseAsync();

				callback(testScripts.ToArray());
			});

			testClient.OpenTestsAsync();
		}
	}

	public class TestScriptReader : ITestScriptReader
	{
		private readonly string _path;

		public TestScriptReader(string path)
		{
			this._path = path;
		}

		public void GetScript(Action<ITestScript> callback)
		{
			var testClient = new AthaTestServiceClient();

			Observable.FromEventPattern<OpenTestCompletedEventArgs>(testClient, "OpenTestCompleted").Subscribe(e =>
			{
				if (e.EventArgs.Cancelled) return;

				ITestScript testScript = null;

				if (e.EventArgs.Error == null)
				{
					testScript = new BasicTestScript(e.EventArgs.Result.Language, e.EventArgs.Result.Name, e.EventArgs.Result.Content);
				}
				else
				{
					// TODO: remove mbox dependency
					MessageBox.Show("Error: " + e.EventArgs.Error.Message, "Error", MessageBoxButton.OK);
				}

				testClient.CloseAsync();

				callback(testScript);
			});

			testClient.OpenTestAsync(this._path);
		}
	}

	public class TestScriptWriter : ITestScriptWriter
	{
		public void SaveScript(ITestScript script)
		{
			var testClient = new AthaTestServiceClient();

			testClient.SaveTestAsync(new TestScriptContract { Name = script.Title, Language = script.Language, Content = script.Content });
		}
	}
}
